package com.soft.base.spring.web.exception;

import com.alibaba.fastjson.JSONException;
import com.soft.base.exception.BizException;
import com.soft.base.exception.BizForbiddenException;
import com.soft.base.exception.ParamException;
import com.soft.base.protocol.ResponseCodes;
import com.soft.base.protocol.Result;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import ai.ii.cloud.common.exception.ServerException;
import java.util.List;
/**
 * class
 *
 * @author user
 * @date 2020/06/05
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionResolver {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object handle(Exception e) {
        if (e instanceof ParamException) {
            log.warn("ParamException", e.getMessage());
            return Result.build(-1, e.getMessage());
        }
        if (e instanceof ServerException) {
            log.warn("ServerException", e.getMessage());
            if (((ServerException)e).getArgs().length > 0) {
                return Result.build(-1, (String) ((ServerException)e).getArgs()[0]);
            }
            return Result.build(-1, e.getMessage());
        }
        if (e instanceof HttpRequestMethodNotSupportedException) {
            return Result.build(-1, "404");
        }
        // JSON解析失败
        if (e instanceof HttpMessageNotReadableException) {
            Throwable cause = e.getCause();
            if (null != cause) {
                if (cause instanceof JSONException) {
                    return Result.build(-1, String.format("数据解析出错 : %s", cause.getMessage()));
                }
            }
        }
        // 参数校验出错
        if (e instanceof MethodArgumentNotValidException) {
            List<ObjectError> errors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
            if (CollectionUtil.isNotEmpty(errors)) {
                return Result.build(-1, errors.get(0).getDefaultMessage());
            }
        }
        if (e instanceof BizException) {
            log.error(e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("500 ERROR");
        }
        if (e instanceof BizForbiddenException) {
            if (!((BizForbiddenException) e).isIgnoreLog()) {
                log.error(e.getMessage(), e);
            }
            if(StrUtil.isNotEmpty(e.getMessage())){
                return Result.build(ResponseCodes.PERMIT_DENIED, e.getMessage());
            }
            return Result.build(ResponseCodes.PERMIT_DENIED,"403 FORBIDDEN");
        }
        log.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("500 ERROR");
    }

}